package com.license.server.controller;

import com.license.server.common.BaseResponse;
import com.license.server.common.ErrorCode;
import com.license.server.common.ResultUtils;
import com.license.server.constant.LicenseConstant;
import com.license.server.entity.LicenseCheckModel;
import com.license.server.entity.dto.LicenseCreatorParamDTO;
import com.license.server.exception.ThrowUtils;
import com.license.server.license.AbstractServerInfos;
import com.license.server.license.LinuxServerInfos;
import com.license.server.license.WindowsServerInfos;
import com.license.server.service.LicenseCreateService;
import de.schlichtherle.license.LicenseContent;
import de.schlichtherle.license.LicenseCreator;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Properties;


@RestController
@Api(value = "License 认证授权", tags = "License 认证授权")
@RequestMapping("/license")
@Slf4j
public class LicenseCreatorController {
    @Resource
    private LicenseCreateService licenseCreateService;

    /**
     * 生成 License 证书
     *
     * @param param 生成证书所需参数
     * @return 生成结果
     */
    @ApiOperation(value = "License 证书生成", notes = "License 证书生成")
    @PostMapping(value = "/generateLicense")
    public BaseResponse<LicenseContent> generateLicense(@RequestBody LicenseCreatorParamDTO param) {
        // 1.校验 Controller 层参数
        ThrowUtils.throwIf(ObjectUtils.isEmpty(param), ErrorCode.PARAMS_ERROR, "生成证书所需参数不能为空");
        // 2.生成证书
        LicenseContent result = licenseCreateService.generateLicense(param);
        // 3.返回结果
        return ResultUtils.success(result);
    }

    /**
     * 下载证书
     *
     * @param response HttpServletResponse
     */
    @ApiOperation(value = "License 证书下载", notes = "License 证书下载")
    @PostMapping("/download")
    public BaseResponse<HttpServletResponse> downloadLicense(HttpServletResponse response) {
        // 本地文件路径
        Properties prop = new Properties();
        try {
            prop.load(LicenseCreator.class.getResourceAsStream("/application.properties"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        String filePath = Paths.get(LicenseConstant.USER_DIR, prop.getProperty("license.license-path")).toString();
        // String filePath = System.getProperty("user.dir") + "/src/main/resources/license/new.png";
        // 下载时文件名（客户端保存时看到的文件名）
        String downloadFileName = "license.lic";
        // String downloadFileName = "new.png";
        try {
            // 使用缓冲输入流读取本地文件
            BufferedInputStream inputStream = new BufferedInputStream(Files.newInputStream(Paths.get(filePath)));
            // 使用HttpServletResponse的输出流将文件发送给客户端
            BufferedOutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            // 设置响应头
            response.setContentType("application/octet-stream"); // 设置为通用二进制文件类型
            // response.setContentType("image/png"); // 根据文件类型设置正确的MIME类型
            response.setHeader("Content-Disposition", "attachment; filename=\"" + downloadFileName + "\"");
            response.setContentLength((int) new File(filePath).length()); // 可选：设置内容长度，有助于浏览器正确处理下载
            // 读取文件内容并写入响应输出流
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            // 关闭流
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            throw new RuntimeException("文件下载失败", e);
        }
        // 返回响应
        return ResultUtils.success(response);
    }

    /**
     * 获取服务器硬件信息
     *
     * @param osName 操作系统类型，如果为空则自动判断
     * @return com.ccx.models.license.LicenseCheckModel
     */
    @ApiOperation(value = "获取服务器硬件信息", notes = "获取服务器硬件信息")
    @GetMapping(value = "/getServerInfos")
    public LicenseCheckModel getServerInfos(@RequestParam(value = "osName", required = false) String osName) {
        // 操作系统类型
        if (StringUtils.isBlank(osName)) {
            osName = System.getProperty("os.name");
        }
        osName = osName.toLowerCase();
        AbstractServerInfos abstractServerInfos = null;
        // 根据不同操作系统类型选择不同的数据获取方法
        if (osName.startsWith("windows")) {
            abstractServerInfos = new WindowsServerInfos();
        } else if (osName.startsWith("linux")) {
            abstractServerInfos = new LinuxServerInfos();
        } else {// 其他服务器类型
            abstractServerInfos = new LinuxServerInfos();
        }
        // 返回硬件信息
        return abstractServerInfos.getServerInfos();
    }
}
